﻿using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Net.Sockets;
using System.Net;
using T.ApiResults;

namespace T.Materials.Read.API.Extension
{
    /// <summary>
    /// 全局异常过滤器
    /// </summary>
    public class GlobalExceptionFilter : IExceptionFilter
    {
        /// <summary>
        /// 日志
        /// </summary>
        protected readonly ILogger<GlobalExceptionFilter> logger;

        /// <summary>
        /// 主机名
        /// </summary>
        protected static readonly string Hostname;

        /// <summary>
        /// IP 地址
        /// </summary>
        protected static readonly string IpAddress;

        static GlobalExceptionFilter()
        {
            //获取并缓存主机名和 IP 地址
            Hostname = Dns.GetHostName();
            var hostentry = Dns.GetHostEntry(Hostname);
            var ipaddress = hostentry.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork);
            IpAddress = ipaddress?.ToString() ?? "未知的 IP 地址";
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志</param>
        public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
        {
            this.logger = logger;
        }

        /// <summary>
        /// 异常处理
        /// </summary>
        /// <param name="context">异常上下文</param>
        public void OnException(ExceptionContext context)
        {
            //获取异常信息
            var exception = context.Exception;
            var exceptionMessage = exception.Message;
            var exceptionStackTrace = exception.StackTrace;

            //获取请求信息
            var requestPath = context.HttpContext.Request.Path;
            var requestMathod = context.HttpContext.Request.Method;

            //记录错误日志 包括 IP 地址、主机名、请求信息、异常信息、异常堆栈跟踪
            logger.LogError("异常发生:\n" +
                        $"主机名: {Hostname}\n" +
                        $"IP 地址: {IpAddress}\n" +
                        $"请求路径: {requestPath}\n" +
                        $"请求方法: {requestMathod}\n" +
                        $"异常信息: {exceptionMessage}\n" +
                        $"异常堆栈跟踪: {exceptionStackTrace.Substring(0, 50)}\n");
            //返回错误响应
            var errorResponse = new ApiResult<string>
            {
                //Code = ResultCode.Fail,
                Message = "服务器内部错误,请稍后再试",
            };
            context.Result = new JsonResult(errorResponse);

            //标记异常已处理,防止进一步传播
            context.ExceptionHandled = true;


        }
    }
}
